import $H from '@/common/free-lib/request.js';
(function() {
	module.exports = {
		upload: upload,
	}

	function getObjectKeys(obj, forKey) {
		var list = [];

		for (var key in obj) {
			if (obj.hasOwnProperty(key)) {
				list.push(forKey ? camSafeUrlEncode(key).toLowerCase() : key);
			}
		}

		return list.sort(function(a, b) {
			a = a.toLowerCase();
			b = b.toLowerCase();
			return a === b ? 0 : a > b ? 1 : -1;
		});
	}

	function camSafeUrlEncode(str) {
		return encodeURIComponent(str).replace(/!/g, '%21').replace(/'/g, '%27').replace(/\(/g, '%28').replace(
			/\)/g,
			'%29').replace(/\*/g, '%2A');
	}

	function obj2str(obj, lowerCaseKey) {
		var i, key, val;
		var list = [];
		var keyList = getObjectKeys(obj);

		for (i = 0; i < keyList.length; i++) {
			key = keyList[i];
			val = obj[key] === undefined || obj[key] === null ? '' : '' + obj[key];
			key = lowerCaseKey ? camSafeUrlEncode(key).toLowerCase() : camSafeUrlEncode(key);
			val = camSafeUrlEncode(val) || '';
			list.push(key + '=' + val);
		}

		return list.join('&');
	};

	function getSkewTime(offset) {
		return Date.now() + (offset || 0);
	};
	// 字符串加密成 hex 字符串
	function sha1(s) {
		var data = new Uint8Array(encodeUTF8(s))
		var i, j, t;
		var l = ((data.length + 8) >>> 6 << 4) + 16,
			s = new Uint8Array(l << 2);
		s.set(new Uint8Array(data.buffer)), s = new Uint32Array(s.buffer);
		for (t = new DataView(s.buffer), i = 0; i < l; i++) s[i] = t.getUint32(i << 2);
		s[data.length >> 2] |= 0x80 << (24 - (data.length & 3) * 8);
		s[l - 1] = data.length << 3;
		var w = [],
			f = [
				function() {
					return m[1] & m[2] | ~m[1] & m[3];
				},
				function() {
					return m[1] ^ m[2] ^ m[3];
				},
				function() {
					return m[1] & m[2] | m[1] & m[3] | m[2] & m[3];
				},
				function() {
					return m[1] ^ m[2] ^ m[3];
				}
			],
			rol = function(n, c) {
				return n << c | n >>> (32 - c);
			},
			k = [1518500249, 1859775393, -1894007588, -899497514],
			m = [1732584193, -271733879, null, null, -1009589776];
		m[2] = ~m[0], m[3] = ~m[1];
		for (i = 0; i < s.length; i += 16) {
			var o = m.slice(0);
			for (j = 0; j < 80; j++)
				w[j] = j < 16 ? s[i + j] : rol(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1),
				t = rol(m[0], 5) + f[j / 20 | 0]() + m[4] + w[j] + k[j / 20 | 0] | 0,
				m[1] = rol(m[1], 30), m.pop(), m.unshift(t);
			for (j = 0; j < 5; j++) m[j] = m[j] + o[j] | 0;
		};
		t = new DataView(new Uint32Array(m).buffer);
		for (var i = 0; i < 5; i++) m[i] = t.getUint32(i << 2);

		var hex = Array.prototype.map.call(new Uint8Array(new Uint32Array(m).buffer), function(e) {
			return (e < 16 ? "0" : "") + e.toString(16);
		}).join("");

		return hex;
	};

	function encodeUTF8(s) {
		var i, r = [],
			c, x;
		for (i = 0; i < s.length; i++)
			if ((c = s.charCodeAt(i)) < 0x80) r.push(c);
			else if (c < 0x800) r.push(0xC0 + (c >> 6 & 0x1F), 0x80 + (c & 0x3F));
		else {
			if ((x = c ^ 0xD800) >> 10 == 0) //对四字节UTF-16转换为Unicode
				c = (x << 10) + (s.charCodeAt(++i) ^ 0xDC00) + 0x10000,
				r.push(0xF0 + (c >> 18 & 0x7), 0x80 + (c >> 12 & 0x3F));
			else r.push(0xE0 + (c >> 12 & 0xF));
			r.push(0x80 + (c >> 6 & 0x3F), 0x80 + (c & 0x3F));
		};
		return r;
	};
	var CryptoJS = CryptoJS || function(g, l) {
		var e = {},
			d = e.lib = {},
			m = function() {},
			k = d.Base = {
				extend: function(a) {
					m.prototype = this;
					var c = new m;
					a && c.mixIn(a);
					c.hasOwnProperty("init") || (c.init = function() {
						c.$super.init.apply(this, arguments)
					});
					c.init.prototype = c;
					c.$super = this;
					return c
				},
				create: function() {
					var a = this.extend();
					a.init.apply(a, arguments);
					return a
				},
				init: function() {},
				mixIn: function(a) {
					for (var c in a) a.hasOwnProperty(c) && (this[c] = a[c]);
					a.hasOwnProperty("toString") && (this.toString = a.toString)
				},
				clone: function() {
					return this.init.prototype.extend(this)
				}
			},
			p = d.WordArray = k.extend({
				init: function(a, c) {
					a = this.words = a || [];
					this.sigBytes = c != l ? c : 4 * a.length
				},
				toString: function(a) {
					return (a || n).stringify(this)
				},
				concat: function(a) {
					var c = this.words,
						q = a.words,
						f = this.sigBytes;
					a = a.sigBytes;
					this.clamp();
					if (f % 4)
						for (var b = 0; b < a; b++) c[f + b >>> 2] |= (q[b >>> 2] >>> 24 - 8 * (b % 4) &
							255) << 24 - 8 * ((f + b) % 4);
					else if (65535 < q.length)
						for (b = 0; b < a; b += 4) c[f + b >>> 2] = q[b >>> 2];
					else c.push.apply(c, q);
					this.sigBytes += a;
					return this
				},
				clamp: function() {
					var a = this.words,
						c = this.sigBytes;
					a[c >>> 2] &= 4294967295 <<
						32 - 8 * (c % 4);
					a.length = g.ceil(c / 4)
				},
				clone: function() {
					var a = k.clone.call(this);
					a.words = this.words.slice(0);
					return a
				},
				random: function(a) {
					for (var c = [], b = 0; b < a; b += 4) c.push(4294967296 * g.random() | 0);
					return new p.init(c, a)
				}
			}),
			b = e.enc = {},
			n = b.Hex = {
				stringify: function(a) {
					var c = a.words;
					a = a.sigBytes;
					for (var b = [], f = 0; f < a; f++) {
						var d = c[f >>> 2] >>> 24 - 8 * (f % 4) & 255;
						b.push((d >>> 4).toString(16));
						b.push((d & 15).toString(16))
					}
					return b.join("")
				},
				parse: function(a) {
					for (var c = a.length, b = [], f = 0; f < c; f += 2) b[f >>> 3] |= parseInt(a.substr(f,
						2), 16) << 24 - 4 * (f % 8);
					return new p.init(b, c / 2)
				}
			},
			j = b.Latin1 = {
				stringify: function(a) {
					var c = a.words;
					a = a.sigBytes;
					for (var b = [], f = 0; f < a; f++) b.push(String.fromCharCode(c[f >>> 2] >>> 24 - 8 * (
						f %
						4) & 255));
					return b.join("")
				},
				parse: function(a) {
					for (var c = a.length, b = [], f = 0; f < c; f++) b[f >>> 2] |= (a.charCodeAt(f) &
							255) << 24 -
						8 * (f % 4);
					return new p.init(b, c)
				}
			},
			h = b.Utf8 = {
				stringify: function(a) {
					try {
						return decodeURIComponent(escape(j.stringify(a)))
					} catch (c) {
						throw Error("Malformed UTF-8 data");
					}
				},
				parse: function(a) {
					return j.parse(unescape(encodeURIComponent(a)))
				}
			},
			r = d.BufferedBlockAlgorithm = k.extend({
				reset: function() {
					this._data = new p.init;
					this._nDataBytes = 0
				},
				_append: function(a) {
					"string" == typeof a && (a = h.parse(a));
					this._data.concat(a);
					this._nDataBytes += a.sigBytes
				},
				_process: function(a) {
					var c = this._data,
						b = c.words,
						f = c.sigBytes,
						d = this.blockSize,
						e = f / (4 * d),
						e = a ? g.ceil(e) : g.max((e | 0) - this._minBufferSize, 0);
					a = e * d;
					f = g.min(4 * a, f);
					if (a) {
						for (var k = 0; k < a; k += d) this._doProcessBlock(b, k);
						k = b.splice(0, a);
						c.sigBytes -= f
					}
					return new p.init(k, f)
				},
				clone: function() {
					var a = k.clone.call(this);
					a._data = this._data.clone();
					return a
				},
				_minBufferSize: 0
			});
		d.Hasher = r.extend({
			cfg: k.extend(),
			init: function(a) {
				this.cfg = this.cfg.extend(a);
				this.reset()
			},
			reset: function() {
				r.reset.call(this);
				this._doReset()
			},
			update: function(a) {
				this._append(a);
				this._process();
				return this
			},
			finalize: function(a) {
				a && this._append(a);
				return this._doFinalize()
			},
			blockSize: 16,
			_createHelper: function(a) {
				return function(b, d) {
					return (new a.init(d)).finalize(b)
				}
			},
			_createHmacHelper: function(a) {
				return function(b, d) {
					return (new s.HMAC.init(a,
						d)).finalize(b)
				}
			}
		});
		var s = e.algo = {};
		return e
	}(Math);
	(function() {
		var g = CryptoJS,
			l = g.lib,
			e = l.WordArray,
			d = l.Hasher,
			m = [],
			l = g.algo.SHA1 = d.extend({
				_doReset: function() {
					this._hash = new e.init([1732584193, 4023233417, 2562383102, 271733878, 3285377520])
				},
				_doProcessBlock: function(d, e) {
					for (var b = this._hash.words, n = b[0], j = b[1], h = b[2], g = b[3], l = b[4], a =
							0; 80 > a; a++) {
						if (16 > a) m[a] = d[e + a] | 0;
						else {
							var c = m[a - 3] ^ m[a - 8] ^ m[a - 14] ^ m[a - 16];
							m[a] = c << 1 | c >>> 31
						}
						c = (n << 5 | n >>> 27) + l + m[a];
						c = 20 > a ? c + ((j & h | ~j & g) + 1518500249) : 40 > a ? c + ((j ^ h ^ g) +
								1859775393) : 60 > a ? c + ((j & h | j & g | h & g) - 1894007588) : c +
							((j ^
								h ^
								g) - 899497514);
						l = g;
						g = h;
						h = j << 30 | j >>> 2;
						j = n;
						n = c
					}
					b[0] = b[0] + n | 0;
					b[1] = b[1] + j | 0;
					b[2] = b[2] + h | 0;
					b[3] = b[3] + g | 0;
					b[4] = b[4] + l | 0
				},
				_doFinalize: function() {
					var d = this._data,
						e = d.words,
						b = 8 * this._nDataBytes,
						g = 8 * d.sigBytes;
					e[g >>> 5] |= 128 << 24 - g % 32;
					e[(g + 64 >>> 9 << 4) + 14] = Math.floor(b / 4294967296);
					e[(g + 64 >>> 9 << 4) + 15] = b;
					d.sigBytes = 4 * e.length;
					this._process();
					return this._hash
				},
				clone: function() {
					var e = d.clone.call(this);
					e._hash = this._hash.clone();
					return e
				}
			});
		g.SHA1 = d._createHelper(l);
		g.HmacSHA1 = d._createHmacHelper(l)
	})();
	(function() {
		var g = CryptoJS,
			l = g.enc.Utf8;
		g.algo.HMAC = g.lib.Base.extend({
			init: function(e, d) {
				e = this._hasher = new e.init;
				"string" == typeof d && (d = l.parse(d));
				var g = e.blockSize,
					k = 4 * g;
				d.sigBytes > k && (d = e.finalize(d));
				d.clamp();
				for (var p = this._oKey = d.clone(), b = this._iKey = d.clone(), n = p.words, j = b
						.words,
						h = 0; h < g; h++) n[h] ^= 1549556828, j[h] ^= 909522486;
				p.sigBytes = b.sigBytes = k;
				this.reset()
			},
			reset: function() {
				var e = this._hasher;
				e.reset();
				e.update(this._iKey)
			},
			update: function(e) {
				this._hasher.update(e);
				return this
			},
			finalize: function(e) {
				var d =
					this._hasher;
				e = d.finalize(e);
				d.reset();
				return d.finalize(this._oKey.clone().concat(e))
			}
		})
	})();

	function isfilename() {
		var num = 20
		const x = "0123456789qwertyuioplkjhgfdsazxcvbnm";
		let tmp = "";
		let date = new Date();
		for (let i = 0; i < num; i++) {
			tmp += x.charAt(Math.ceil(Math.random() * 100000000) % x.length);
		}
		var year = date.getFullYear();
		var month = date.getMonth() + 1;
		var day = date.getDate();
		month = (month > 9) ? month : ("0" + month);
		day = (day < 10) ? ("0" + day) : day;
		var today = year + month + day;
		return 'attachment/storage/files/' + today + "/" + tmp;
	}

	function upload(item, oss_data, success, fail, progress, cancelTask) {
		var suffix = '';
		oss_data.filename = isfilename();
		if (item.fileType) {
			suffix = '.' + item.fileType;
			item.suffix = suffix;
			is_up(item, oss_data, success, fail, progress, cancelTask);
		} else {
			let re = new RegExp('data:image/(?<ext>.*?);base64,.*')
			let res = re.exec(item.path);
			if (res) {
				suffix = '.' + res.groups.ext;
				item.suffix = suffix;
				is_up(item, oss_data, success, fail, progress, cancelTask);
			} else {
				// #ifdef H5
				const xhr = new XMLHttpRequest();
				xhr.open('GET', item.path);
				xhr.responseType = 'blob';
				xhr.onload = () => {
					var blob = xhr.response;
					var suffix = blob.type.split('/').pop(); // 获取文件的后缀   
					item.suffix = '.' + suffix;
					is_up(item, oss_data, success, fail, progress, cancelTask);
				};
				xhr.send();
				// #endif
				// #ifndef H5

				item.suffix = item.path.substr(item.path.lastIndexOf("."));
				is_up(item, oss_data, success, fail, progress, cancelTask);

				// #endif


			}
		}
	}


	function is_up(item, oss_data, success, fail, progress, cancelTask) {

		if (oss_data.oss == 3) { //腾讯云 计算签名

			var url = 'banmi.php/Upload/upload_api'
			$H.post(url, 'app', {
				token: true,
				datalist: {},
			}).then(ret => {

				let oss_data = ret.data.data;
				var filename = oss_data.filename + item.suffix

				var options = {};
				var data = oss_data;
				var pathname;
				var Key = '';
				options.Pathname = '/';
				options.UseRawKey = '';
				if (options.UseRawKey) {
					pathname = options.Pathname || options.pathname || '/' + Key;
				} else {
					pathname = options.Pathname || options.pathname || Key;
					pathname.indexOf('/') !== 0 && (pathname = '/' + pathname);
				} // ForceSignHost明确传入false才不加入host签名

				var method = 'post'
				var queryParams = {};
				var headers = {
					"Host": oss_data.url
				}
				var formatString = [method, pathname, obj2str(queryParams,
						true),
					obj2str(headers, true), ''
				].join('\n');
				var now = Math.round(getSkewTime(0) / 1000) - 1;
				var exp = now;
				var Expires = undefined;
				if (Expires === undefined) {
					exp += 900; // 签名过期时间为当前 + 900s
				} else {
					exp += Expires * 1 || 0;
				} // 要用到的 Authorization 参数列表
				var KeyTime = '';
				var qSignTime = KeyTime || now + ';' + exp;
				var qKeyTime = KeyTime || now + ';' + exp;
				var qAk = data.credentials.tmpSecretId;

				var qSignAlgorithm = 'sha1';
				var stringToSign = ['sha1', qSignTime, sha1(formatString)
					.toString(), ''
				].join(
					'\n');
				var qHeaderList = getObjectKeys(headers, true).join(';')
					.toLowerCase();
				var SecretKey = data.credentials.tmpSecretKey;
				var qUrlParamList = getObjectKeys(queryParams, true).join(
					';').toLowerCase();
				var signKey = CryptoJS.HmacSHA1(qKeyTime, SecretKey)
					.toString(); // 步骤二：构成 FormatString
				var qSignature = CryptoJS.HmacSHA1(stringToSign, signKey)
					.toString(); // 步骤五：构造 Authorization

				var authorization = ['q-sign-algorithm=' + qSignAlgorithm,
					'q-ak=' + qAk,
					'q-sign-time=' + qSignTime, 'q-key-time=' + qKeyTime,
					'q-header-list=' +
					qHeaderList, 'q-url-param-list=' + qUrlParamList,
					'q-signature=' +
					qSignature
				].join('&');

				var formData = {
					'key': filename,
					'success_action_status': 200,
					'Signature': authorization,
					'x-cos-security-token': data.credentials.sessionToken
				};
				var headerKeys = ['Cache-Control', 'Content-Type',
					'Content-Disposition', 'Content-Encoding', 'Expires',
					'x-cos-storage-class', 'x-cos-security-token',
					'x-ci-security-token'
				];
				var bucket = oss_data.bucket
				var region = oss_data.region
				oss_data.url = 'https://' + bucket + '.cos.' + region + '.myqcloud.com/';
				oss_data.filename = filename;
				oss_data.formData = formData;
				ajaxUpload(item, oss_data, success, fail, progress, cancelTask);

			});




		} else {
			ajaxUpload(item, oss_data, success, fail, progress, cancelTask);
		}


	}

	function ajaxUpload(item, oss_data, success, fail, progress, cancelTask) {
 

		var formData = {
			'banmi_system': uni.getStorageSync('system'),
			'banmi_uniPlatform': uni.getStorageSync('uniPlatform'),
			'banmi_model': uni.getStorageSync('model'),
			'banmi_browserName': uni.getStorageSync('browserName'),
			'banmi_platform': uni.getStorageSync('platform'),
			'banmi_screenHeight': uni.getStorageSync('screenHeight'),
			'banmi_deviceBrand': uni.getStorageSync('deviceBrand'),
			'banmi_brand': uni.getStorageSync('brand'),
			'banmi_appVersion': uni.getStorageSync('appVersion'),
			'banmi_deviceModel': uni.getStorageSync('deviceModel'),
			'banmi_model': uni.getStorageSync('model'),
			'banmi_osAndroidAPILevel': uni.getStorageSync('osAndroidAPILevel'),
			'banmi_romName': uni.getStorageSync('romName'),
			'banmi_romVersion': uni.getStorageSync('romVersion'),
			'banmi_system': uni.getStorageSync('system'),
			'banmi_token': uni.getStorageSync('token')
		};

		if (oss_data.token) {
			formData.banmi_token = oss_data.token;
		}



		if (oss_data.oss == 2) { //阿里云
			oss_data.filename = oss_data.filename + item.suffix
			var formData = {
				key: oss_data.filename, //文件名
				policy: oss_data.policy, //后台获取超时时间
				OSSAccessKeyId: oss_data.accessid, //后台获取临时ID
				success_action_status: '200', //让服务端返回200,不然，默认会返回204
				signature: oss_data.signature //后台获取签名
			};
		} else if (oss_data.oss == 1) { //七牛云
			oss_data.filename = oss_data.filename + item.suffix
			var formData = {
				'token': oss_data.token,
				'key': oss_data.filename,
			};
		} else if (oss_data.oss == 3) { //腾讯云
			var formData = oss_data.formData;
		}

		var uploadTask = wx.uploadFile({
			url: oss_data.url,
			filePath: item.path,
			name: 'file',
			formData: formData,
			success: function(res) {

				try {
					if (oss_data.oss == 0) { //本地服务器
						var dataString = res.data
						var dataObject = JSON.parse(dataString);
						if (dataObject.status != 200) {
							uni.showToast({
								title: dataObject.msg,
								icon: 'error'
							})
							return
						}
						var imageUrl = dataObject.data.url;
						dataObject.imageURL = imageUrl;
					} else if (oss_data.oss == 1) { //七牛云oss
						if (res.statusCode != 200) {
							var dataObjecta = JSON.parse(res.data);
							uni.showModal({
								title: '七牛云配置错误',
								content: dataObjecta.error,
								showCancel: false,
								success: function(res) {

								}
							});
							return
						}
						var dataObject = {};
						dataObject.imageURL = oss_data.filename;
					} else {
						if (res.statusCode != 200) {
							var data = res.data;

							uni.showModal({
								title: '云oss配置错误',
								content: data,
								showCancel: false,
								success: function(res) {

								}
							});
							return
						}
						var dataObject = {};
						dataObject.imageURL = oss_data.filename;
					}


					if (success) {
						success(dataObject);
					}
				} catch (e) {
					if (fail) {
						fail(e);
					}
				}
			},
			fail: function(error) {

				uni.showToast({
					title: '连接不成功，可能存在跨域问题',
					icon: 'error',
					duration: 5000,
				})
				return
				if (fail) {
					fail(error);
				}
			}
		})
		uploadTask.onProgressUpdate((res) => {
			progress && progress(res)
		})
		cancelTask && cancelTask(() => {
			uploadTask.abort()
		})
	}

})();